using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.TeamFoundation.VersionControl.Client;
using Ltf.Remoting.TeamFoundation;
using Ltf.Remoting.RemoteEvents;
using System.IO;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Collections;
using Ltf.MonitorLizard.Helpers;

namespace Ltf.MonitorLizard.Forms
{
	[FormType(FormTypes.Unshelve)]
	public partial class Unshelve : Form
	{
		private Workspace workspace;
		private ImageList fileImages;
		private Ltf.MonitorLizard.Helpers.FileIcons fileIcons;
		Dictionary<ListView, int> sortColumnIndex;
		Dictionary<ListView, bool> sortDesc;
		private TFServerConnection connection;

		public Unshelve(string[] pathList, LizardEventArgs args)
			:this (pathList[0])
		{		}

		public Unshelve(string path)
		{
			InitializeComponent();
			connection = ServerConnections.GetConnectionForPath(path);
			workspace = connection.GetWorkspace(path);
			fileImages = new ImageList();
			fileIcons = new Ltf.MonitorLizard.Helpers.FileIcons(fileImages);
			sortColumnIndex = new Dictionary<ListView, int>();
			sortColumnIndex.Add(lvwShelvesets, 0);
			sortColumnIndex.Add(lvwDetails, 0);
			sortDesc = new Dictionary<ListView, bool>();
			sortDesc.Add(lvwShelvesets, false);
			sortDesc.Add(lvwDetails, false);

			txtUserName.Text = workspace.OwnerName;
			LoadShelveSets(workspace.OwnerName);
		}

		private void btnFind_Click(object sender, EventArgs e)
		{
			LoadShelveSets(txtUserName.Text);
		}

		private void LoadShelveSets(string userName)
		{
			Shelveset[] shelvesets = new Shelveset[0];
			try
			{
				shelvesets = workspace.VersionControlServer.QueryShelvesets(string.Empty, userName);
			}
			catch (Exception ex)
			{
				MessageBox.Show("LizardTF failed to find shelvesets with the error:\r\n" + ex.Message, "Find Shelvesets Failed",
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			lvwShelvesets.Items.Clear();
			lvwDetails.Items.Clear();
			foreach (Shelveset ss in shelvesets)
			{
				ListViewItem lvi = new ListViewItem(new string[] {ss.Name,ss.CreationDate.ToShortDateString(),
					ss.OwnerName,ss.Comment});
				lvi.Tag = ss;
				lvwShelvesets.Items.Add(lvi);

			}
		}

		private void lvwShelvesets_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
		{
			if (lvwShelvesets.SelectedItems.Count == 1 && lvwShelvesets.SelectedItems[0].Tag is Shelveset)
			{
				Shelveset ss = (Shelveset)lvwShelvesets.SelectedItems[0].Tag;
				PendingSet[] pss = workspace.VersionControlServer.QueryShelvedChanges(ss);
				lvwDetails.SmallImageList = fileImages;
				lvwDetails.Items.Clear();
				foreach (PendingSet ps in pss)
				{
					foreach (PendingChange pc in ps.PendingChanges)
					{
						ListViewItem lvi = new ListViewItem(new string[] { Path.GetFileName( pc.ServerItem),
							pc.ChangeType.ToString(), Path.GetDirectoryName(pc.ServerItem) });
						if (pc.ItemType == ItemType.Folder)
							lvi.ImageKey = "$folder";
						else
							lvi.ImageKey = fileIcons.LoadIconForFileExtension(System.IO.Path.GetExtension(pc.ServerItem));
						lvi.Tag = pc;
						lvi.Checked = true;
						lvwDetails.Items.Add(lvi);
					}
				}
				List<string> lines = new List<string>();
				foreach (WorkItemCheckinInfo wici in ss.WorkItemInfo)
				{
					WorkItem wi = wici.WorkItem;
					lines.Add(string.Format("{0}\t{1}", wi.Id, wi.Title));
				}
				txtWorkItems.Lines = lines.ToArray();
			}
		}

		void lsvChanges_ColumnClick(object sender, ColumnClickEventArgs e)
		{
			ListView lv = sender as ListView;
			lv.Columns[sortColumnIndex[lv]].ImageKey = null;
			if (sortColumnIndex[lv] == e.Column)
				sortDesc[lv] = !sortDesc[lv];
			else
			{
				sortDesc[lv] = false;
				sortColumnIndex[lv] = e.Column;
			}
			lv.ListViewItemSorter = (IComparer)new Sorter(sortColumnIndex[lv], sortDesc[lv]);
			lv.Sort();

		}

		private void btnDelete_Click(object sender, EventArgs e)
		{
			if (lvwShelvesets.SelectedItems.Count==1)
			{
				Shelveset ss = (Shelveset)lvwShelvesets.SelectedItems[0].Tag;
				DeleteShelveset(ss);
			}
		}

		private void DeleteShelveset(Shelveset shelveSet)
		{
			string name = shelveSet.Name;
			try
			{
				workspace.VersionControlServer.DeleteShelveset(shelveSet);
			}
			catch (Exception ex)
			{
				MessageBox.Show("Delete Shelveset Failed", string.Format("LizardTF failed to delete the shelveset '{0}' with the error:\r\n{1}",
					name, ex.Message), MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			MessageBox.Show("Deleted Shelveset", string.Format("LizardTF deleted the shelveset '{0}'",name),
				MessageBoxButtons.OK, MessageBoxIcon.None);
		}

		private void btnUnshelve_Click(object sender, EventArgs e)
		{
			if (lvwShelvesets.SelectedItems.Count == 1)
			{
				Shelveset ss = (Shelveset)lvwShelvesets.SelectedItems[0].Tag;
				UnshelveShelveset(ss);
			}
		}

		private void UnshelveShelveset(Shelveset shelveSet)
		{
			string name = shelveSet.Name;
			try
			{
				if (ckbPartialUnshelve.Checked)
				{
					List<ItemSpec> itemsList = new List<ItemSpec>();
					foreach (ListViewItem lvi in lvwDetails.Items)
					{
						if (lvi.Checked)
							itemsList.Add(new ItemSpec(((PendingChange)lvi.Tag).ServerItem, RecursionType.None));
					}
					workspace.Unshelve(shelveSet.Name, shelveSet.OwnerName,itemsList.ToArray());
				}
				else
					workspace.Unshelve(shelveSet.Name, shelveSet.OwnerName);
			}
			catch (Exception ex)
			{
				MessageBox.Show(string.Format("LizardTF failed to unshelved the shelveset '{0}' with the error:\r\n{1}",
					name, ex.Message), "Unshelve Shelveset Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			MessageBox.Show(string.Format("LizardTF unshelved the shelveset '{0}'", name),
				"Unshelved Shelveset", MessageBoxButtons.OK, MessageBoxIcon.None);

			if (!ckbPreserveShelveset.Checked)
				DeleteShelveset(shelveSet);
		}

		private void lvwDetails_ItemCheck(object sender, ItemCheckEventArgs e)
		{
			
		}

		MouseButtons lastDetailButton = MouseButtons.None;

		private void lvwDetails_MouseDown(object sender, MouseEventArgs e)
		{
			lastDetailButton = e.Button;
		}

		private void lvwDetails_Click(object sender, EventArgs e)
		{
			if (lastDetailButton == MouseButtons.Right)
			{
				if (lvwDetails.SelectedItems.Count == 1 && lvwDetails.SelectedItems[0].Tag is PendingChange)
				{
					PendingChange pc = (PendingChange)lvwDetails.SelectedItems[0].Tag;
					if (pc.ItemType == ItemType.File)
					{
						string tempCopy = Path.Combine(connection.Settings.TempPath,
							Path.GetFileName(pc.ServerItem) + ".shelved");
						pc.DownloadShelvedFile(tempCopy);
						ContextMenus.LoadDiffMenu(cmsShelveItems, pc.ServerItem, tempCopy, "Compare with ",connection, workspace);
						cmsShelveItems.Show(lvwDetails, lvwDetails.PointToClient(MousePosition));
					}
				}
			}
		}

		private void ckbPartialUnshelve_CheckedChanged(object sender, EventArgs e)
		{
			lvwDetails.CheckBoxes = ckbPartialUnshelve.Checked;
		}

		private void btnClose_Click(object sender, EventArgs e)
		{
			Close();
		}
	}
}